package com.qf.filter;

import com.qf.utils.JwtUtil;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 *
 * 关于登录  的全局过滤器
 * @author lixu
 */
@Component
public class LoginFilterGlobal implements GlobalFilter, Ordered {

    public static final String LOGIN_PATH = "ogin";  // l  ogin   toL  ogin

    public static final String TOKEN = "token";

    public static final String REDIRECTURL = "http://localhost:10010/customer/toLogin";
    /**
     * 执行方法
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        String path = request.getURI().getPath();
        System.out.println("请求路径:" + path);
        //1:判断当前请求是否是登录的请求
        if(!path.contains(LOGIN_PATH)){
            //1.2:  不是登录的请求
            //2:判断当前用户是否有令牌
            String token = getToken(request);
            if(!StringUtils.isEmpty(token)){
                //2.1:有令牌 校验令牌是真是假

                try {
                    JwtUtil.parseJWT(token);
                    //代表成功 解释成功
                    //---  令牌是真的  允许它访问欢迎页面
                    //TODO 可以继续校验令牌的真与假 双重校验  jti: 获取redis 详细的 （用户的角色、权限 ）
                } catch (Exception e) {
                    //代表失败 解析失败了
                    //---  令牌是假的  要求用户重定向到登录页面去登录
                    //响应码
                    response.setStatusCode(HttpStatus.SEE_OTHER);//303 看别处 就是重定向
                    //重定向的路径  http://localhost:10010/customer/login  去登录页面
                    //  响应头  location:
                    response.getHeaders().add(HttpHeaders.LOCATION,REDIRECTURL);
                    //开始响应
                    return response.setComplete();
                }
            }else{
                //2.2:无令牌  要求用户重定向到登录页面去登录
                //响应码
                response.setStatusCode(HttpStatus.SEE_OTHER);//303 看别处 就是重定向
                //重定向的路径  http://localhost:10010/customer/login  去登录页面
                //  响应头  location:
                response.getHeaders().add(HttpHeaders.LOCATION,REDIRECTURL);
                //开始响应
                return response.setComplete();
            }
        }
        //1.1： 是为了登录的请求放行
        //放行
        return chain.filter(exchange);
    }

    /**
     * 获取Cookie中的令牌
     * @param request
     * @return
     */
    private String getToken(ServerHttpRequest request) {
        MultiValueMap<String, HttpCookie> cookies = request.getCookies();
        if(null != cookies && cookies.size() > 0){
            HttpCookie httpCookie = cookies.getFirst(TOKEN);
            if(null != httpCookie){
                String value = httpCookie.getValue();
                if(!StringUtils.isEmpty(value)){
                    //有令牌
                    return value;
                }
            }

        }
        //Cookie没有  自然就没有令牌
        return null;
    }




    /**
     *  过滤器的执行顺序
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
